﻿using ScottPlot.Avalonia;
using Digitalmes.Core.Services;
using Digitalmes.Core.Domain.Eitites;

namespace Digitalmes.AvaloniaUI.ViewModels;

/// <summary>
/// 存档数据图表
/// </summary>
public sealed partial class TurntableArchivePlotViewModel : ViewModelBase
{
    private readonly ITurntableArchiveService _turntableArchiveService;
    private readonly IParamStandardService _paramStandardService;

    // 查询--开始时间
    [ObservableProperty]
    public partial DateTime? StartDate { get; set; }

    // 查询--结束时间
    [ObservableProperty]
    public partial DateTime? EndDate { get; set; }

    /// <summary>
    /// 正转时间图
    /// </summary>
    public AvaPlot PlotForwardRotationTime { get; }

    /// <summary>
    /// 反转时间图
    /// </summary>
    public AvaPlot PlotReverseRotationTime { get; }

    /// <summary>
    /// 重复定位精度A图
    /// </summary>
    public AvaPlot PlotRepeatabilityA { get; }

    /// <summary>
    /// 重复定位精度B图
    /// </summary>
    public AvaPlot PlotRepeatabilityB { get; }

    /// <summary>
    /// 轴向重复定位精度
    /// </summary>
    public AvaPlot PlotRepeatabilityAxialA { get; }

    /// <summary>
    /// 轴向重复定位精度（偏载）
    /// </summary>
    public AvaPlot PlotRepeatabilityAxialB { get; }

    // 查询
    [RelayCommand]
    private async Task Query()
    {
        // 查询存档数据
        var archiveData = await _turntableArchiveService.GetListAsync(StartDate, EndDate);

        double[] forwardRotationTimeDataY = [.. archiveData.Where(s => s.Rotation == Rotation.Forward).Select(m => m.ForwardRotationTime)];
        BindLinePlot(PlotForwardRotationTime, forwardRotationTimeDataY);

        double[] reverseRotationTimeDataY = [.. archiveData.Where(s => s.Rotation == Rotation.Reverse).Select(m => m.ReverseRotationTime)];
        BindLinePlot(PlotReverseRotationTime, reverseRotationTimeDataY);

        var (_, minA, maxA) = await _paramStandardService.GetStandardAsync("repeatability_A");
        double[] repeatabilityADataY = [.. archiveData.Where(s => s.Rotation == Rotation.Forward).Select(m => m.Repeatability1)];
        BindLinePlot(PlotRepeatabilityA, repeatabilityADataY, minA, maxA);

        var (_, minB, maxB) = await _paramStandardService.GetStandardAsync("repeatability_B");
        double[] repeatabilityBDataY = [.. archiveData.Where(s => s.Rotation == Rotation.Reverse).Select(m => m.Repeatability2)];
        BindLinePlot(PlotRepeatabilityB, repeatabilityBDataY, minB, maxB);

        var (_, minAxialA, maxAxialA) = await _paramStandardService.GetStandardAsync("repeatability_axial_A");
        double[] repeatabilityAxialADataY = [.. archiveData.Where(s => s.Rotation == Rotation.Forward).Select(m => m.RepeatabilityAxial1)]; // 轴向都是正转
        BindLinePlot(PlotRepeatabilityAxialA, repeatabilityAxialADataY, minAxialA, maxAxialA);

        var (_, minAxialB, maxAxialB) = await _paramStandardService.GetStandardAsync("repeatability_axial_B");
        double[] repeatabilityAxialBDataY = [.. archiveData.Where(s => s.Rotation == Rotation.Forward).Select(m => m.RepeatabilityAxial2)]; // 轴向都是正转
        BindLinePlot(PlotRepeatabilityAxialB, repeatabilityAxialBDataY, minAxialB, maxAxialB);
    }

    public TurntableArchivePlotViewModel(
        ITurntableArchiveService turntableArchiveService, 
        IParamStandardService paramStandardService)
    {
        _turntableArchiveService = turntableArchiveService;
        _paramStandardService = paramStandardService;

        // 存档数据图表
        PlotForwardRotationTime = new AvaPlot();
        PlotForwardRotationTime.Plot.Title("正转时间");
        PlotForwardRotationTime.Plot.YLabel("时间(s)");
        PlotForwardRotationTime.Plot.Font.Automatic();

        PlotReverseRotationTime = new AvaPlot();
        PlotReverseRotationTime.Plot.Title("反转时间");
        PlotReverseRotationTime.Plot.YLabel("时间(s)");
        PlotReverseRotationTime.Plot.Font.Automatic();

        PlotRepeatabilityA = new AvaPlot();
        PlotRepeatabilityA.Plot.Title("重复定位精度0°");
        PlotRepeatabilityA.Plot.YLabel("距离(mm)");
        PlotRepeatabilityA.Plot.Font.Automatic();

        PlotRepeatabilityB = new AvaPlot();
        PlotRepeatabilityB.Plot.Title("重复定位精度180°");
        PlotRepeatabilityB.Plot.YLabel("距离(mm)");
        PlotRepeatabilityB.Plot.Font.Automatic();

        PlotRepeatabilityAxialA = new AvaPlot();
        PlotRepeatabilityAxialA.Plot.Title("轴向重复定位精度");
        PlotRepeatabilityAxialA.Plot.YLabel("距离(mm)");
        PlotRepeatabilityAxialA.Plot.Font.Automatic();

        PlotRepeatabilityAxialB = new AvaPlot();
        PlotRepeatabilityAxialB.Plot.Title("轴向重复定位精度（偏载）");
        PlotRepeatabilityAxialB.Plot.YLabel("距离(mm)");
        PlotRepeatabilityAxialB.Plot.Font.Automatic();
    }

    // 绑定 Line 类型 Plot
    private static void BindLinePlot<T>(AvaPlot avaPlot, T[] dataY, double? minLimit = default, double? maxLimit = default)
        where T : struct
    {
        avaPlot.Plot.Clear();
        if (minLimit is not null)
        {
            avaPlot.Plot.Add.HorizontalLine(minLimit.Value, width: 1, color: ScottPlot.Color.FromColor(System.Drawing.Color.Red)); // 下限线
        }
        if (maxLimit is not null)
        {
            avaPlot.Plot.Add.HorizontalLine(maxLimit.Value, width: 1, color: ScottPlot.Color.FromColor(System.Drawing.Color.Red)); // 上限线
        }

        avaPlot.Plot.Add.Signal(dataY);
        avaPlot.Plot.Axes.AutoScale(); // reset limits to fit the data
        avaPlot.Refresh(); // 立即刷新图表
    }
}
